package com.it.mybatis.spring.sqlSession;


import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.sql.*;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;

/**
 * @author 胡凯
 * @create 2021/11/25 17:44
 */
public class DefaultSqlSession implements SqlSession {
    // 直接使用java提供的
    private Connection connection;
    // 直接使用java
    private Map<String, XNode> mapperElement;

    // 通过构造方法传参来初始化类
    public DefaultSqlSession(Connection connection, Map<String, XNode> mapperElement) {
        this.connection = connection;
        this.mapperElement = mapperElement;
    }

    @Override
    public <T> T selectOne(String statement) throws SQLException, ClassNotFoundException, InvocationTargetException, NoSuchMethodException, InstantiationException, IllegalAccessException {
        XNode xNode = mapperElement.get(statement);
        PreparedStatement preparedStatement = connection.prepareStatement(xNode.getSql());
        ResultSet resultSet = preparedStatement.executeQuery();
        List<T> list = result2Object(resultSet, Class.forName(xNode.getResultType()));
        return list.get(0);

    }
    // 转换为我们的结果pojo赋值
    public <T> List<T> result2Object(ResultSet resultSet, Class<?> clz) throws SQLException, IllegalAccessException, InstantiationException, NoSuchMethodException, InvocationTargetException {
        List<T> list = new ArrayList<>();
        // 获取到表头数据
        ResultSetMetaData metaData = resultSet.getMetaData();
        // 获取列
        int columnCount = metaData.getColumnCount();
        while (resultSet.next()) {
            // 强转为T泛型
            T obj = (T) clz.newInstance();
            // 给对象赋值
            for (int i = 0; i < columnCount; i++) {
                Object value = resultSet.getObject(i);
                String columnName = metaData.getColumnName(i);
                // 主要构建setXxxYyy 的方法名，遵循驼峰命名规范
                String setMethod = "set" + columnName.substring(0, 1).toUpperCase() + columnName.substring(1);
                Method method;
                // 时间类型
                if (value instanceof Timestamp) {
                    method = clz.getMethod(setMethod, Date.class);
                } else {
                    // 其他类型
                    method = clz.getMethod(setMethod, value.getClass());
                }
                method.invoke(obj, value);
            }
            list.add(obj);
        }
        return list;
    }
    // 入参进行装换
    public void buildParameter(PreparedStatement preparedStatement, Object parameter, Map<Integer, String> parameterMap){
        // 参数个数
        int prmSize =parameterMap.size();

    }
    @Override
    public <T> T selectOne(String statement, Object parameter) throws SQLException {
        XNode xNode = mapperElement.get(statement);
        Map<Integer, String> parameterMap = xNode.getParameter();
        PreparedStatement preparedStatement = connection.prepareStatement(xNode.getSql());
        return null;
    }

    @Override
    public <T> List<T> selectList(String statement) throws SQLException, ClassNotFoundException, InvocationTargetException, NoSuchMethodException, InstantiationException, IllegalAccessException {
        XNode xNode = mapperElement.get(statement);
        PreparedStatement preparedStatement = connection.prepareStatement(xNode.getSql());
        ResultSet resultSet = preparedStatement.executeQuery();
        return result2Object(resultSet, Class.forName(xNode.getResultType()));
    }

    @Override
    public <T> List<T> selectList(String statement, Object parameter) {
        return null;
    }

    @Override
    public void close() {
        if (null == connection) {
            return;
        }
        try {
            connection.close();
        } catch (SQLException throwables) {
            throwables.printStackTrace();
        }
    }
}
